Skip to content

[libc][math] Refactor cos implementation to header-only in src/__support/math folder. #151883

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

bassiounix
Copy link
Contributor

@bassiounix bassiounix commented Aug 3, 2025

Copy link
Contributor Author

bassiounix commented Aug 3, 2025

This stack of pull requests is managed by Graphite. Learn more about stacking.

@llvmbot
Copy link
Member

llvmbot commented Aug 3, 2025

@llvm/pr-subscribers-libc

Author: Muhammad Bassiouni (bassiounix)

Changes

Part of #147386

in preparation for: https://discourse.llvm.org/t/rfc-make-clang-builtin-math-functions-constexpr-with-llvm-libc-to-support-c-23-constexpr-math-functions/86450


Patch is 33.10 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/151883.diff

16 Files Affected:

  • (modified) libc/shared/math.h (+1)
  • (added) libc/shared/math/cos.h (+23)
  • (modified) libc/src/__support/math/CMakeLists.txt (+47)
  • (added) libc/src/__support/math/cos.h (+173)
  • (renamed) libc/src/__support/math/range_reduction_double_common.h (+14-4)
  • (renamed) libc/src/__support/math/range_reduction_double_fma.h (+9-1)
  • (renamed) libc/src/__support/math/range_reduction_double_nofma.h (+9-1)
  • (renamed) libc/src/__support/math/sincos_eval.h (+6-2)
  • (modified) libc/src/math/generic/CMakeLists.txt (+6-44)
  • (modified) libc/src/math/generic/cos.cpp (+2-153)
  • (modified) libc/src/math/generic/sin.cpp (+8-6)
  • (modified) libc/src/math/generic/sincos.cpp (+8-6)
  • (modified) libc/src/math/generic/tan.cpp (+4-3)
  • (modified) libc/test/shared/CMakeLists.txt (+1)
  • (modified) libc/test/shared/shared_math_test.cpp (+2-1)
  • (modified) utils/bazel/llvm-project-overlay/libc/BUILD.bazel (+55-46)
diff --git a/libc/shared/math.h b/libc/shared/math.h
index ea645f0afedbc..a5581ed4272a3 100644
--- a/libc/shared/math.h
+++ b/libc/shared/math.h
@@ -32,6 +32,7 @@
 #include "math/atanhf16.h"
 #include "math/cbrt.h"
 #include "math/cbrtf.h"
+#include "math/cos.h"
 #include "math/erff.h"
 #include "math/exp.h"
 #include "math/exp10.h"
diff --git a/libc/shared/math/cos.h b/libc/shared/math/cos.h
new file mode 100644
index 0000000000000..c498550f098b4
--- /dev/null
+++ b/libc/shared/math/cos.h
@@ -0,0 +1,23 @@
+//===-- Shared cos function -------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_MATH_COS_H
+#define LLVM_LIBC_SHARED_MATH_COS_H
+
+#include "shared/libc_common.h"
+#include "src/__support/math/cos.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::cos;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_MATH_COS_H
diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt
index fe928a8fadd5e..24844063fcd24 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -357,6 +357,24 @@ add_header_library(
     libc.src.__support.macros.optimization
 )
 
+add_header_library(
+  cos
+  HDRS
+    cos.h
+  DEPENDS
+    libc.src.__support.math.sincos_eval
+    libc.hdr.errno_macros
+    libc.src.errno.errno
+    libc.src.__support.FPUtil.double_double
+    libc.src.__support.FPUtil.dyadic_float
+    libc.src.__support.FPUtil.except_value_utils
+    libc.src.__support.FPUtil.fenv_impl
+    libc.src.__support.FPUtil.fp_bits
+    libc.src.__support.math.range_reduction_double
+    libc.src.__support.macros.optimization
+)
+
+
 add_header_library(
   erff
   HDRS
@@ -613,3 +631,32 @@ add_header_library(
     libc.src.__support.macros.optimization
     libc.src.__support.macros.properties.cpu_features
 )
+
+add_header_library(
+  range_reduction_double
+  HDRS
+    range_reduction_double_common.h
+    range_reduction_double_fma.h
+    range_reduction_double_nofma.h
+  DEPENDS
+    libc.src.__support.FPUtil.double_double
+    libc.src.__support.FPUtil.dyadic_float
+    libc.src.__support.FPUtil.fp_bits
+    libc.src.__support.FPUtil.fma
+    libc.src.__support.FPUtil.multiply_add
+    libc.src.__support.FPUtil.nearest_integer
+    libc.src.__support.common
+    libc.src.__support.integer_literals
+)
+
+add_header_library(
+  sincos_eval
+  HDRS
+    sincos_eval.h
+  DEPENDS
+    libc.src.__support.FPUtil.double_double
+    libc.src.__support.FPUtil.dyadic_float
+    libc.src.__support.FPUtil.multiply_add
+    libc.src.__support.FPUtil.polyeval
+    libc.src.__support.integer_literals
+)
diff --git a/libc/src/__support/math/cos.h b/libc/src/__support/math/cos.h
new file mode 100644
index 0000000000000..0802f9e4f6e49
--- /dev/null
+++ b/libc/src/__support/math/cos.h
@@ -0,0 +1,173 @@
+//===-- Implementation header for cos ---------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LIBC_SRC___SUPPORT_MATH_COS_H
+#define LIBC_SRC___SUPPORT_MATH_COS_H
+
+#include "range_reduction_double_common.h"
+#include "sincos_eval.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/double_double.h"
+#include "src/__support/FPUtil/dyadic_float.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"            // LIBC_UNLIKELY
+#include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA
+
+#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+#include "range_reduction_double_fma.h"
+#else
+#include "range_reduction_double_nofma.h"
+#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace math {
+
+LIBC_INLINE static constexpr double cos(double x) {
+  using namespace range_reduction_double_internal;
+  using DoubleDouble = fputil::DoubleDouble;
+  using FPBits = typename fputil::FPBits<double>;
+  FPBits xbits(x);
+
+  uint16_t x_e = xbits.get_biased_exponent();
+
+  DoubleDouble y;
+  unsigned k = 0;
+  LargeRangeReduction range_reduction_large;
+
+  // |x| < 2^16.
+  if (LIBC_LIKELY(x_e < FPBits::EXP_BIAS + FAST_PASS_EXPONENT)) {
+    // |x| < 2^-7
+    if (LIBC_UNLIKELY(x_e < FPBits::EXP_BIAS - 7)) {
+      // |x| < 2^-27
+      if (LIBC_UNLIKELY(x_e < FPBits::EXP_BIAS - 27)) {
+        // Signed zeros.
+        if (LIBC_UNLIKELY(x == 0.0))
+          return 1.0;
+
+        // For |x| < 2^-27, |cos(x) - 1| < |x|^2/2 < 2^-54 = ulp(1 - 2^-53)/2.
+        return fputil::round_result_slightly_down(1.0);
+      }
+      // No range reduction needed.
+      k = 0;
+      y.lo = 0.0;
+      y.hi = x;
+    } else {
+      // Small range reduction.
+      k = range_reduction_small(x, y);
+    }
+  } else {
+    // Inf or NaN
+    if (LIBC_UNLIKELY(x_e > 2 * FPBits::EXP_BIAS)) {
+      if (xbits.is_signaling_nan()) {
+        fputil::raise_except_if_required(FE_INVALID);
+        return FPBits::quiet_nan().get_val();
+      }
+      // cos(+-Inf) = NaN
+      if (xbits.get_mantissa() == 0) {
+        fputil::set_errno_if_required(EDOM);
+        fputil::raise_except_if_required(FE_INVALID);
+      }
+      return x + FPBits::quiet_nan().get_val();
+    }
+
+    // Large range reduction.
+    k = range_reduction_large.fast(x, y);
+  }
+
+  DoubleDouble sin_y, cos_y;
+
+  [[maybe_unused]] double err =
+      math::sincos_eval_internal::sincos_eval(y, sin_y, cos_y);
+
+  // Look up sin(k * pi/128) and cos(k * pi/128)
+#ifdef LIBC_MATH_HAS_SMALL_TABLES
+  // Memory saving versions.  Use 65-entry table.
+  auto get_idx_dd = [](unsigned kk) -> DoubleDouble {
+    unsigned idx = (kk & 64) ? 64 - (kk & 63) : (kk & 63);
+    DoubleDouble ans = SIN_K_PI_OVER_128[idx];
+    if (kk & 128) {
+      ans.hi = -ans.hi;
+      ans.lo = -ans.lo;
+    }
+    return ans;
+  };
+  DoubleDouble msin_k = get_idx_dd(k + 128);
+  DoubleDouble cos_k = get_idx_dd(k + 64);
+#else
+  // Fast look up version, but needs 256-entry table.
+  // -sin(k * pi/128) = sin((k + 128) * pi/128)
+  // cos(k * pi/128) = sin(k * pi/128 + pi/2) = sin((k + 64) * pi/128).
+  DoubleDouble msin_k = SIN_K_PI_OVER_128[(k + 128) & 255];
+  DoubleDouble cos_k = SIN_K_PI_OVER_128[(k + 64) & 255];
+#endif // LIBC_MATH_HAS_SMALL_TABLES
+
+  // After range reduction, k = round(x * 128 / pi) and y = x - k * (pi / 128).
+  // So k is an integer and -pi / 256 <= y <= pi / 256.
+  // Then cos(x) = cos((k * pi/128 + y)
+  //             = cos(y) * cos(k*pi/128) - sin(y) * sin(k*pi/128)
+  DoubleDouble cos_k_cos_y = fputil::quick_mult(cos_y, cos_k);
+  DoubleDouble msin_k_sin_y = fputil::quick_mult(sin_y, msin_k);
+
+  DoubleDouble rr = fputil::exact_add<false>(cos_k_cos_y.hi, msin_k_sin_y.hi);
+  rr.lo += msin_k_sin_y.lo + cos_k_cos_y.lo;
+
+#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+  return rr.hi + rr.lo;
+#else
+  using Float128 = typename fputil::DyadicFloat<128>;
+  double rlp = rr.lo + err;
+  double rlm = rr.lo - err;
+
+  double r_upper = rr.hi + rlp; // (rr.lo + ERR);
+  double r_lower = rr.hi + rlm; // (rr.lo - ERR);
+
+  // Ziv's rounding test.
+  if (LIBC_LIKELY(r_upper == r_lower))
+    return r_upper;
+
+  Float128 u_f128, sin_u, cos_u;
+  if (LIBC_LIKELY(x_e < FPBits::EXP_BIAS + FAST_PASS_EXPONENT))
+    u_f128 = range_reduction_small_f128(x);
+  else
+    u_f128 = range_reduction_large.accurate();
+
+  math::sincos_eval_internal::sincos_eval(u_f128, sin_u, cos_u);
+
+  auto get_sin_k = [](unsigned kk) -> Float128 {
+    unsigned idx = (kk & 64) ? 64 - (kk & 63) : (kk & 63);
+    Float128 ans = SIN_K_PI_OVER_128_F128[idx];
+    if (kk & 128)
+      ans.sign = Sign::NEG;
+    return ans;
+  };
+
+  // -sin(k * pi/128) = sin((k + 128) * pi/128)
+  // cos(k * pi/128) = sin(k * pi/128 + pi/2) = sin((k + 64) * pi/128).
+  Float128 msin_k_f128 = get_sin_k(k + 128);
+  Float128 cos_k_f128 = get_sin_k(k + 64);
+
+  // cos(x) = cos((k * pi/128 + u)
+  //        = cos(u) * cos(k*pi/128) - sin(u) * sin(k*pi/128)
+  Float128 r = fputil::quick_add(fputil::quick_mul(cos_k_f128, cos_u),
+                                 fputil::quick_mul(msin_k_f128, sin_u));
+
+  // TODO: Add assertion if Ziv's accuracy tests fail in debug mode.
+  // https://github.com/llvm/llvm-project/issues/96452.
+
+  return static_cast<double>(r);
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+}
+
+} // namespace math
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_SRC___SUPPORT_MATH_COS_H
diff --git a/libc/src/math/generic/range_reduction_double_common.h b/libc/src/__support/math/range_reduction_double_common.h
similarity index 98%
rename from libc/src/math/generic/range_reduction_double_common.h
rename to libc/src/__support/math/range_reduction_double_common.h
index a93ee25201813..0cace009abf90 100644
--- a/libc/src/math/generic/range_reduction_double_common.h
+++ b/libc/src/__support/math/range_reduction_double_common.h
@@ -20,6 +20,10 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
+namespace math {
+
+namespace range_reduction_double_internal {
+
 #ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
 static constexpr unsigned SPLIT = fputil::DefaultSplit<double>::VALUE;
 #else
@@ -40,7 +44,7 @@ using Float128 = LIBC_NAMESPACE::fputil::DyadicFloat<128>;
 // Error bound:
 //   |(x - k * pi/128) - (u_hi + u_lo)| <= max(ulp(ulp(u_hi)), 2^-119)
 //                                      <= 2^-111.
-LIBC_INLINE unsigned range_reduction_small(double x, DoubleDouble &u) {
+LIBC_INLINE static unsigned range_reduction_small(double x, DoubleDouble &u) {
   // Values of -pi/128 used for inputs with absolute value <= 2^16.
   // The first 3 parts are generated with (53 - 21 = 32)-bit precision, so that
   // the product k * MPI_OVER_128[i] is exact.
@@ -267,13 +271,15 @@ struct LargeRangeReduction {
   }
 #endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
+  LIBC_INLINE LargeRangeReduction() = default;
+
 private:
   // Index of x in the look-up table ONE_TWENTY_EIGHT_OVER_PI.
-  unsigned idx;
+  unsigned idx = 0;
   // x scaled down by 2^(-16 *(idx - 3))).
-  double x_reduced;
+  double x_reduced = 0;
   // Parts of (x * 128/pi) mod 1.
-  double y_hi, y_lo;
+  double y_hi = 0, y_lo = 0;
   DoubleDouble y_mid;
 };
 
@@ -369,6 +375,10 @@ static constexpr Float128 SIN_K_PI_OVER_128_F128[65] = {
 };
 #endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
+} // namespace range_reduction_double_internal
+
+} // namespace math
+
 } // namespace LIBC_NAMESPACE_DECL
 
 #endif // LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_DOUBLE_COMMON_H
diff --git a/libc/src/math/generic/range_reduction_double_fma.h b/libc/src/__support/math/range_reduction_double_fma.h
similarity index 98%
rename from libc/src/math/generic/range_reduction_double_fma.h
rename to libc/src/__support/math/range_reduction_double_fma.h
index 160fb2461fe21..156e51befcd04 100644
--- a/libc/src/math/generic/range_reduction_double_fma.h
+++ b/libc/src/__support/math/range_reduction_double_fma.h
@@ -16,10 +16,14 @@
 #include "src/__support/common.h"
 #include "src/__support/macros/config.h"
 #include "src/__support/macros/optimization.h"
-#include "src/math/generic/range_reduction_double_common.h"
+#include "src/__support/math/range_reduction_double_common.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
+namespace math {
+
+namespace range_reduction_double_internal {
+
 using LIBC_NAMESPACE::fputil::DoubleDouble;
 
 LIBC_INLINE unsigned LargeRangeReduction::fast(double x, DoubleDouble &u) {
@@ -341,6 +345,10 @@ LIBC_INLINE constexpr DoubleDouble SIN_K_PI_OVER_128[] = {
 #endif // !LIBC_MATH_HAS_SMALL_TABLES
 };
 
+} // namespace range_reduction_double_internal
+
+} // namespace math
+
 } // namespace LIBC_NAMESPACE_DECL
 
 #endif // LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_DOUBLE_FMA_H
diff --git a/libc/src/math/generic/range_reduction_double_nofma.h b/libc/src/__support/math/range_reduction_double_nofma.h
similarity index 98%
rename from libc/src/math/generic/range_reduction_double_nofma.h
rename to libc/src/__support/math/range_reduction_double_nofma.h
index 9d13d246ce91f..d89cd72e94005 100644
--- a/libc/src/math/generic/range_reduction_double_nofma.h
+++ b/libc/src/__support/math/range_reduction_double_nofma.h
@@ -16,10 +16,14 @@
 #include "src/__support/common.h"
 #include "src/__support/macros/config.h"
 #include "src/__support/macros/optimization.h"
-#include "src/math/generic/range_reduction_double_common.h"
+#include "src/__support/math/range_reduction_double_common.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
+namespace math {
+
+namespace range_reduction_double_internal {
+
 using fputil::DoubleDouble;
 
 LIBC_INLINE unsigned LargeRangeReduction::fast(double x, DoubleDouble &u) {
@@ -342,6 +346,10 @@ LIBC_INLINE constexpr DoubleDouble SIN_K_PI_OVER_128[] = {
 #endif // !LIBC_MATH_HAS_SMALL_TABLES
 };
 
+} // namespace range_reduction_double_internal
+
+} // namespace math
+
 } // namespace LIBC_NAMESPACE_DECL
 
 #endif // LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_DOUBLE_NOFMA_H
diff --git a/libc/src/math/generic/sincos_eval.h b/libc/src/__support/math/sincos_eval.h
similarity index 98%
rename from libc/src/math/generic/sincos_eval.h
rename to libc/src/__support/math/sincos_eval.h
index 41a4c75849ff4..fc741af19551f 100644
--- a/libc/src/math/generic/sincos_eval.h
+++ b/libc/src/__support/math/sincos_eval.h
@@ -18,7 +18,9 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
-namespace generic {
+namespace math {
+
+namespace sincos_eval_internal {
 
 using fputil::DoubleDouble;
 using Float128 = fputil::DyadicFloat<128>;
@@ -131,7 +133,9 @@ LIBC_INLINE void sincos_eval(const Float128 &u, Float128 &sin_u,
                            COS_COEFFS[6]);
 }
 
-} // namespace generic
+} // namespace sincos_eval_internal
+
+} // namespace math
 
 } // namespace LIBC_NAMESPACE_DECL
 
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 44c17cf5b0770..b224808e54e45 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -275,23 +275,6 @@ add_header_library(
     libc.src.__support.common
 )
 
-add_header_library(
-  range_reduction_double
-  HDRS
-    range_reduction_double_common.h
-    range_reduction_double_fma.h
-    range_reduction_double_nofma.h
-  DEPENDS
-    libc.src.__support.FPUtil.double_double
-    libc.src.__support.FPUtil.dyadic_float
-    libc.src.__support.FPUtil.fp_bits
-    libc.src.__support.FPUtil.fma
-    libc.src.__support.FPUtil.multiply_add
-    libc.src.__support.FPUtil.nearest_integer
-    libc.src.__support.common
-    libc.src.__support.integer_literals
-)
-
 add_header_library(
   sincosf_utils
   HDRS
@@ -313,18 +296,6 @@ add_header_library(
     libc.src.__support.common
 )
 
-add_header_library(
-  sincos_eval
-  HDRS
-    sincos_eval.h
-  DEPENDS
-    libc.src.__support.FPUtil.double_double
-    libc.src.__support.FPUtil.dyadic_float
-    libc.src.__support.FPUtil.multiply_add
-    libc.src.__support.FPUtil.polyeval
-    libc.src.__support.integer_literals
-)
-
 add_entrypoint_object(
   cos
   SRCS
@@ -332,16 +303,7 @@ add_entrypoint_object(
   HDRS
     ../cos.h
   DEPENDS
-    .range_reduction_double
-    .sincos_eval
-    libc.hdr.errno_macros
-    libc.src.errno.errno
-    libc.src.__support.FPUtil.double_double
-    libc.src.__support.FPUtil.dyadic_float
-    libc.src.__support.FPUtil.except_value_utils
-    libc.src.__support.FPUtil.fenv_impl
-    libc.src.__support.FPUtil.fp_bits
-    libc.src.__support.macros.optimization
+    libc.src.__support.math.cos
 )
 
 add_entrypoint_object(
@@ -420,8 +382,8 @@ add_entrypoint_object(
   HDRS
     ../sin.h
   DEPENDS
-    .range_reduction_double
-    .sincos_eval
+    libc.src.__support.math.range_reduction_double
+    libc.src.__support.math.sincos_eval
     libc.hdr.errno_macros
     libc.src.errno.errno
     libc.src.__support.FPUtil.double_double
@@ -480,8 +442,8 @@ add_entrypoint_object(
   HDRS
     ../sincos.h
   DEPENDS
-    .range_reduction_double
-    .sincos_eval
+    libc.src.__support.math.range_reduction_double
+    libc.src.__support.math.sincos_eval
     libc.hdr.errno_macros
     libc.src.errno.errno
     libc.src.__support.FPUtil.double_double
@@ -553,7 +515,7 @@ add_entrypoint_object(
   HDRS
     ../tan.h
   DEPENDS
-    .range_reduction_double
+    libc.src.__support.math.range_reduction_double
     libc.hdr.errno_macros
     libc.src.errno.errno
     libc.src.__support.FPUtil.double_double
diff --git a/libc/src/math/generic/cos.cpp b/libc/src/math/generic/cos.cpp
index 5da0f86812a89..aabf3bc7edcb0 100644
--- a/libc/src/math/generic/cos.cpp
+++ b/libc/src/math/generic/cos.cpp
@@ -7,161 +7,10 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/math/cos.h"
-#include "hdr/errno_macros.h"
-#include "src/__support/FPUtil/FEnvImpl.h"
-#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/FPUtil/double_double.h"
-#include "src/__support/FPUtil/dyadic_float.h"
-#include "src/__support/FPUtil/except_value_utils.h"
-#include "src/__support/common.h"
-#include "src/__support/macros/config.h"
-#include "src/__support/macros/optimization.h"            // LIBC_UNLIKELY
-#include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA
-#include "src/math/generic/range_reduction_double_common.h"
-#include "src/math/generic/sincos_eval.h"
-
-#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
-#include "range_reduction_double_fma.h"
-#else
-#include "range_reduction_double_nofma.h"
-#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+#include "src/__support/math/cos.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
-using DoubleDouble = fputil::DoubleDouble;
-using Float128 = typename fputil::DyadicFloat<128>;
-
-LLVM_LIBC_FUNCTION(double, cos, (double x)) {
-  using FPBits = typename fputil::FPBits<double>;
-  FPBits xbits(x);
-
-  uint16_t x_e = xbits.get_biased_exponent();
-
-  DoubleDouble y;
-  unsigned k;
-  LargeRangeReduction range_reduction_large{};
-
-  // |x| < 2^16.
-  if (LIBC_LIKELY(x_e < FPBits::EXP_BIAS + FAST_PASS_EXPONENT)) {
-    // |x| < 2^-7
-    if (LIBC_UNLIKELY(x_e < FPBits::EXP_BIAS - 7)) {
-      // |x| < 2^-27
-      if (LIBC_UNLIKELY(x_e < FPBits::EXP_BIAS - 27)) {
-        // Signed zeros.
-        if (LIBC_UNLIKELY(x == 0.0))
-          return 1.0;
-
-        // For |x| < 2^-27, |cos(x) - 1| < |x|^2/2 < 2^-54 = ulp(1 - 2^-53)/2.
-        return fputil::round_result_slightly_down(1.0);
-      }
-      // No range reduction needed.
-      k = 0;
-      y.lo = 0.0;
-      y.hi = x;
-    } else {
-      // Small range reduction.
-      k = range_reduction_small(x, y);
-    }
-  } else {
-    // Inf or NaN
-    if (LIBC_UNLIKELY(x_e > 2 * FPBits::EXP_BIAS)) {
-      if (xbits.is_signaling_nan()) {
-        fputil::raise_except_if_required(FE_INVALID);
-        return FPBits::quiet_nan().get_val();
-      }
-      // cos(+-Inf) = NaN
-      if (xbits.get_mantissa() == 0) {
-        fputil::set_errno_if_required(EDOM);
-        fputil::raise_except_if_required(FE_INVALID);
-      }
-      return x + FPBits::quiet_nan().get_val();
-    }
-
-    // Large range reduction.
-    k = range_reduction_large.fast(x, y);
-  }
-
-  DoubleDouble sin_y, cos_y;
-
-  [[maybe_unused]] double err = generic::sincos_eval(y, sin_y, cos_y);
-
-  // Look up sin(k * pi/128) and cos(k * pi/128)
-#ifdef LIBC_MATH_HAS_SMALL_TABLES
-  // Memory saving versions.  Use 65-entry table.
-  auto get_idx_dd = [](unsigned kk) -> DoubleDouble {
-    unsigned idx = (kk & 64) ? 64 - (kk & 63) : (kk & 63);
-    DoubleDouble ans = SIN_K_PI_OVER_128[idx];
-    if (kk & 128) {
-      ans.hi = -ans.hi;
-      ans.lo = -ans.lo;
-    }
-    return ans;
-  };
-  DoubleDouble msin_k = get_idx_dd(k + 128);
-  DoubleDouble cos_k = get_idx_dd(k + 64);
-#else
-  // Fast look up version, but needs 256-entry table.
-  // -sin(k * pi/128) = sin((k + 128) * pi/128)
-  // cos(k * pi/128) = sin(k * pi/128 + pi/2) =...
[truncated]

@bassiounix bassiounix requested review from lntue and removed request for keith, rupprecht and aaronmondal August 3, 2025 19:27
@bassiounix bassiounix force-pushed the users/bassiounix/spr/08-03-_libc_math_refactor_cos_implementation_to_header-only_in_src___support_math_folder branch from a9b8611 to a6db72e Compare August 5, 2025 03:31
@bassiounix bassiounix force-pushed the users/bassiounix/spr/08-03-_libc_math_refactor_cbrtf_implementation_to_header-only_in_src___support_math_folder branch from 4aa6063 to ae312dc Compare August 5, 2025 03:31
@bassiounix bassiounix force-pushed the users/bassiounix/spr/08-03-_libc_math_refactor_cos_implementation_to_header-only_in_src___support_math_folder branch 2 times, most recently from a66f719 to 37848d7 Compare August 5, 2025 03:46
@bassiounix bassiounix force-pushed the users/bassiounix/spr/08-03-_libc_math_refactor_cos_implementation_to_header-only_in_src___support_math_folder branch from 37848d7 to 14a8e8a Compare August 5, 2025 03:48
@bassiounix bassiounix force-pushed the users/bassiounix/spr/08-03-_libc_math_refactor_cbrtf_implementation_to_header-only_in_src___support_math_folder branch 9 times, most recently from fd28f6c to 50a8445 Compare August 8, 2025 15:22
Base automatically changed from users/bassiounix/spr/08-03-_libc_math_refactor_cbrtf_implementation_to_header-only_in_src___support_math_folder to main August 8, 2025 15:28
@bassiounix bassiounix force-pushed the users/bassiounix/spr/08-03-_libc_math_refactor_cos_implementation_to_header-only_in_src___support_math_folder branch from 14a8e8a to 83954bc Compare August 8, 2025 15:30
Comment on lines 365 to 367
libc.src.__support.math.sincos_eval
libc.hdr.errno_macros
libc.src.errno.errno
libc.src.__support.FPUtil.double_double
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: reorder dependency list.

@bassiounix bassiounix force-pushed the users/bassiounix/spr/08-03-_libc_math_refactor_cos_implementation_to_header-only_in_src___support_math_folder branch from 83954bc to 9e2a863 Compare August 9, 2025 15:18
@bassiounix bassiounix force-pushed the users/bassiounix/spr/08-03-_libc_math_refactor_cos_implementation_to_header-only_in_src___support_math_folder branch from 9e2a863 to 81d16f9 Compare August 9, 2025 15:28
Copy link
Contributor Author

bassiounix commented Aug 9, 2025

Merge activity

  • Aug 9, 3:28 PM UTC: Graphite rebased this pull request as part of a merge.
  • Aug 9, 3:51 PM UTC: @bassiounix merged this pull request with Graphite.

@bassiounix bassiounix merged commit e86c9b6 into main Aug 9, 2025
19 checks passed
@bassiounix bassiounix deleted the users/bassiounix/spr/08-03-_libc_math_refactor_cos_implementation_to_header-only_in_src___support_math_folder branch August 9, 2025 15:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bazel "Peripheral" support tier build system: utils/bazel libc
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants